/**************************
* @Summary
* @Author 20009200303 赵传博
* @Date 2022/4/3
*****************************/

#include "Lexer.h"
#include "Error.h"
using namespace Lexer;

Token_value Lexer::curr_tok;
double Lexer::number_value;
ifstream* Lexer::input;
string Lexer::string_value;
int Lexer::line_number = 1;
map<string, double> Lexer::table;

Lexer::Token_value Lexer::get_token() {
    char ch = 0;
    cin.get(ch);
    switch (ch) {
        case 0:
            return curr_tok = END;
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9': case '.':
            cin.putback(ch);
            cin >> number_value;
            return curr_tok = NUMBER;
        case '*': case '/': case '+':
        case '-': case '(': case ')': case '=':
            return curr_tok = Token_value(ch);
        case '\n': case ';':
            ++line_number;
            return curr_tok = PRINT;
        default:
            if(isalpha(ch)){
                string_value = ch;
                while(cin.get(ch) && isalnum(ch)) string_value.push_back(ch);
                cin.putback(ch);
                return curr_tok = NAME;
            }
            myError::error("bad token");
            return curr_tok = PRINT;

    }
}

Lexer::Token_value Lexer::get_token(ifstream* inStream) {
    char ch = 0;
    ch = inStream->get();
    switch (ch) {
        case 0:
            return curr_tok = END;
        case '0': case '1': case '2': case '3': case '4': case '5':
        case '6': case '7': case '8': case '9': case '.':
            inStream->putback(ch);
            *inStream >> number_value;
            return curr_tok = NUMBER;
        case '*': case '/': case '+':
        case '-': case '(': case ')': case '=':
            return curr_tok = Token_value(ch);
        case '\n': case ';':
            ++line_number;
            return curr_tok = PRINT;
        default:
            if(isalpha(ch)){
                string_value = ch;
                ch = inStream->get();
                while(ch != '\n' && isalnum(ch)){
                    string_value.push_back(ch);
                    ch = inStream->get();
                }
                inStream->seekg(-2, ios::cur);
                inStream->putback(ch);
                return curr_tok = NAME;
            }
            return curr_tok = PRINT;

    }
}